
#include <stdio.h>
#include <string.h>

#define GETC()    (getc(stdin))
#define PUTS(str) (printf ("%s", str))

#define PUTC(c)   (putc(c, stdout))

#define min(x,y) (((x)<(y))?(x):(y))
#define max(x,y) (((x)>(y))?(x):(y))

#define MAXBAL 40

void
stateis(char *msg, char lastc, char nextc, int parens, int ibal, int balp[])
{
  fprintf( stderr,  "%s:\t%c%c %d? %d: ",  msg, lastc, nextc, parens, ibal);
  for( ; ibal > 0; ibal--) 
    {
      fprintf( stderr, "%d: [%d]; ", ibal,  balp[ibal]);
    }
  fprintf( stderr, "\n");
}

int
main ( int argc, char *argv[])
{
  char lastc;
  char nextc;

  int reporting;	/* annotate the output		*/
  int balp[MAXBAL];    	/* where on the "paren stack" are the tokens */
  int ibal = 0;         /* how many outstanding tokens	*/
  int parens = 0;      	/* # outstanding parens		*/

  balp[0] = 0;

  if ( argc > 1 && strcmp("-r", argv[1])==0)
    {
      reporting = 1;
    }

  for( lastc = ' '; ((nextc = GETC()) != EOF); lastc = nextc)
    {
      stateis("EACHCH", lastc, nextc, parens, ibal, balp);
      if ( nextc == '(' )
        {
	  parens++;
	  if ( lastc != '_' )
	    {
	      PUTC(lastc);
	    }
	  else 
            {
	      stateis("OPEN  ", lastc, nextc, parens, ibal, balp);
	      ibal++; ibal = min( ibal, MAXBAL);
	      PUTS("\n_(");
	      nextc = ' ';
	      balp[ibal] = parens;
            }

	  stateis("PARENS", lastc, nextc, parens, ibal, balp);
        }
      else
	{
	  PUTC(lastc);
	  if ( lastc == '\n' && reporting)
	    {
	      printf( "%4d%4d\t", parens, balp[ibal]);
	    }
	  if ( nextc == ')' ) 
	    {
	      stateis("Q_BALP", lastc, nextc, parens, ibal, balp);
	      if ( parens == balp[ibal] )
		{
		  ibal--; ibal = max(ibal, 0);
		  PUTS(")\n");
		  nextc = ' ';
		}
	      parens--;
	    }
	}
    }
  PUTC(lastc);
  return( parens);
}

